package com.xiaogeqq1034.core;

import java.util.Random;
import java.util.Scanner;

/**
 * @Desc 
 * @author xiehui
 *`@date 2014年7月4日
 * @mailto xiaogeqq1034@163.com
 */
public class Core {
	
	public Block[][] blocks=new Block[4][4];
	public void merge()
	{
		String ch=MonitorKey();
		switch (ch)
		{
		   case "a" :left(); break;
		   case "s" :down();break;
		   case "w" :up();break;
		   case "d" :right();break;
		   default:
			   System.out.println("illgel input ");
		}
		createnewblock();
		showdisplay();
	}
	public void createnewblock()
	{
		Random rand=new Random();
		int[] a=new int[17];
		int Value=0;
		   a=findavailableblock();
		if (a[16]>=1) {
			   Value=a[rand.nextInt(a[16])];
			   blocks[Value/4][Value%4].value=((rand.nextInt(4)%2)==1)?4:2;
		//	  System.out.println(Value/4+" "+Value%4+" "+Value);
			}
		 
		
	}
	public int[] findavailableblock()
	{
		int[] a=new int[17];
		int k=0;
		for (int i=0;i<4;i++)
			for(int j=0;j<4;j++)
				if (blocks[i][j].value==0)
				{
					a[k]=i*4+j;
					k++;
				}
		a[16]=k;
	/*	for (int i=0;i<17;i++)
			System.out.print(a[i]+" ");
		System.out.println();*/
		return a;
		
					//live
		
	}
	/**
	 * check the game die or not
	 * 
	 * @return -1 die 1 live;
	 * number is below the 16
	 */
	public int fail()
	{
	/*	int flag=-1; //die
		for (int i=0;i<4;i++)
			for(int j=0;j<4;j++)
				if (blocks[i][j].value==0) flag=i*4+j; //live
		if (flag==-1) {System.out.println("you die");}
		return flag;*/
		int flag=-1;
		int a[]=findavailableblock();
		if (a[16]>=1) {flag=1;}
		else {up();down();right();left();
			showdisplay();
			int b[]=findavailableblock();
	     	  if (b[16]>0)
	     	  {flag=1;}else
				  {
					  System.out.println("you die");
					  flag=-1;
				  }
		  }
		return flag;
	}
	public void createboard()
	{
		//Block[][] block2=new Block[4][4];
		for (int i=0;i<4;i++)
			for(int j=0;j<4;j++)
			{
				Block block = new Block(i,j,0);
				blocks[i][j] = block;
				
			}
		
	}
	public void up()
	{
		int[] a= new int[6];
		int size=4;
	  for (int i=0;i<4;i++)
	  { 
		for (int j=0;j<4;j++)
		{
			a[j]=blocks[j][i].value;
			blocks[j][i].value=0;
		}
		
		a[4]=-1;a[5]=size;
		a=Minmize(size,a);
		a=merginlingrow(a[5],a);
		while(a[4]==-1)
		{
			merginlingrow(a[5], a);
			a=Minmize(a[5], a);
		}
	//	for (int j=a[5];j<4)
	//	for (int j=0;j<4;j++)
	//		System.out.print(a[j]+" ");
		for (int j=0;j<4;j++)
		{
			blocks[j][i].value=a[j];
		}
	
	  }
	}
	/**
	 * Minmize the numberrow
	 * @param size
	 * @param a
	 * @return if it is minmize
	 */
	public int[] Minmize(int size,int[] a)
	{
		int flag=1;  //is min
		int[] b={0,0,0,0,0,0};
		int i=0;
		int j=0;
		int cutsize=0;
		while(j<size)
		{
			if (a[j]!=0) {b[i]=a[j];i++;j++;}
			else {j++;flag=-1;cutsize++;}//not min
		}
		b[4]=flag;
		b[5]=size-cutsize;
	//	for (int k=0;k<6;k++)
		//	System.out.print(b[k]+" ");
		return b;
	}
	/**
	 * Merge Minmize numberrow;
	 * @param size
	 * @param a
	 * @return
	 */
	public int[] merginlingrow(int size,int[] a)
	{
		int i=0;
		while (i<size)
		{
		  if(i+1==size) {i++;}
		  else
			if ( a[i]==a[i+1] )
			{
				a[i]=a[i]+a[i+1];
				a[i+1]=0;
				i=i+2;
				a[4]=-1;
			}else{
				i++;
			}
		}
	//	for (int k=0;k<6;k++)
		//	System.out.print(a[k]+" ");
		return a;
	}
	
	public void down()
	{
		int[] a= new int[6];
		int size=4;
	  for (int i=0;i<4;i++)
	  { 
		for (int j=0;j<4;j++)
		{
			a[j]=blocks[j][i].value;
			blocks[j][i].value=0;
		}
		
		a[4]=-1;a[5]=size;
		a=Minmize(size,a);
		a=merginlingrow(a[5],a);
		while(a[4]==-1)
		{
			merginlingrow(a[5], a);
			a=Minmize(a[5], a);
		}
	//	for (int j=a[5];j<4)
	//	for (int j=0;j<4;j++)
	//		System.out.print(a[j]+" ");
		for (int j=0;j<a[5];j++)
		{
			blocks[3-j][i].value=a[a[5]-j-1];
		}
	
	  }
		
	}
	public void left()
	{
		int[] a= new int[6];
		int size=4;
	  for (int i=0;i<4;i++)
	  { 
		for (int j=0;j<4;j++)
		{
			a[j]=blocks[i][j].value;
			blocks[i][j].value=0;
		}
		
		a[4]=-1;a[5]=size;
		a=Minmize(size,a);
		a=merginlingrow(a[5],a);
		while(a[4]==-1)
		{
			merginlingrow(a[5], a);
			a=Minmize(a[5], a);
		}
	//	for (int j=a[5];j<4)
	//	for (int j=0;j<4;j++)
	//		System.out.print(a[j]+" ");
		for (int j=0;j<a[5];j++)
		{
			blocks[i][j].value=a[j];
		}
	
	  }
	}
	public void right()
	{
		int[] a= new int[6];
		int size=4;
	  for (int i=0;i<4;i++)
	  { 
		for (int j=0;j<4;j++)
		{
			a[j]=blocks[i][j].value;
			blocks[i][j].value=0;
		}
		
		a[4]=-1;a[5]=size;
		a=Minmize(size,a);
		a=merginlingrow(a[5],a);
		while(a[4]==-1)
		{
			merginlingrow(a[5], a);
			a=Minmize(a[5], a);
		}
	//	for (int j=a[5];j<4)
	//	for (int j=0;j<4;j++)
	//		System.out.print(a[j]+" ");
		for (int j=0;j<a[5];j++)
		{
			blocks[i][3-j].value=a[a[5]-j-1];
		}
	
	  }
	}

	public void showdisplay()
	{
	//	System.out.println("==============================");
		for(int i=0;i<4;i++)
		{
			for(int j=0;j<4;j++)
				System.out.print(blocks[i][j].getValue()+" ");
			System.out.println();
		}
	}
	public String MonitorKey()
	{
		Scanner input=new Scanner(System.in);
		System.out.println("Please input the next setp 'w' is up 's' is down 'a' is left 'd' is right");
		String ch=input.nextLine();
		return ch;
	}
}
